/*	
*	File: igmpv2_packet.h
*	Date: 2011/11/25
*	User: Ronmaru
*	Desctiption: IGMP version 2 packet class
*/

#include "pcraft-tool.h"

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <string>
#include <istream>
#include <iostream>
#include <ostream>

using boost::asio::deadline_timer;
namespace posix_time = boost::posix_time;

class IGMPv2packet
{
public:
//   IGMPv2header(boost::asio::io_service& io_service, UDPheader header, UDPpseudoheader pseudo_header,
//     const std::string &body)
//     : udp_resolver_(io_service), udp_socket_(io_service, raw::v4()),
//     udp_header_(header), udp_pseudo_header_(pseudo_header), udp_body_(body), encapsulate_ip_(1)
//   {
//     raw::resolver::query query(raw::v4(), pseudo_header.GetDestinationAddress().to_string(), "");
//     udp_destination_ = *udp_resolver_.resolve(query);
// 
//     udp_socket_.connect(udp_destination_);
//   }

  IGMPv2packet(boost::asio::io_service& io_service, IPV4header ipv4_header, IGMPv2header igmpv2_header)
    : igmpv2_resolver_(io_service), igmpv2_socket_(io_service, raw::v4()), 
    igmpv2_header_(igmpv2_header), ipv4_header_(ipv4_header), encapsulate_ip_(0)
  {
    raw::resolver::query query(raw::v4(), ipv4_header.GetDestinationAddress().to_string(), "");
    igmpv2_destination_ = *igmpv2_resolver_.resolve(query);

    igmpv2_socket_.connect(igmpv2_destination_);
    const ip_hdrincl opt_ip_hdrincl(1);
    igmpv2_socket_.set_option(opt_ip_hdrincl);
  }

  void send()
  {
    boost::asio::streambuf request_buffer;
    std::ostream os(&request_buffer);
    
    igmpv2_header_.ComputeChecksum();
    if (encapsulate_ip_) {
      //os << udp_header_ << udp_body_;
    } else {
      os << ipv4_header_ << igmpv2_header_;
    }

    igmpv2_socket_.send(request_buffer.data());
  }

  int encapsulate_ip_;
  raw::resolver igmpv2_resolver_;
  raw::endpoint igmpv2_destination_;
  raw::socket igmpv2_socket_;

  IGMPv2header igmpv2_header_;
  IPV4header ipv4_header_;
};